package com.strongbj.iot.devices.amazonNewReader.response.coder;

import com.strongbj.iot.devices.amazonNewReader.message.NewReaderMessage;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;

public class NewReaderDecoder extends DelimiterBasedFrameDecoder{

	public NewReaderDecoder(int maxFrameLength) {
		super(maxFrameLength, Unpooled.copiedBuffer(
				new byte[]{0x5a,Integer.valueOf("A5", 16).byteValue()})); // 通过5A A5解决粘包问题
	}
	
private static final int RESERVATIONS_SIZE = 15; //数据保留区长度
	
	private static final int RCR_SIZE = 2;			// 效验码的长度
	
	private static final int Time_SIZR =4;         // 时间戳的长度
	
	// 头部起始码 0x5a 0xa5
	private static final int HEADER_SIZE = 8;		// 数据头的长度
	
	private static final int VALID_LENGHT=HEADER_SIZE+RESERVATIONS_SIZE+RCR_SIZE; // 有效长度

	// 地址码
	private byte[] address = new byte[3];

	// 类型码
	private byte type;

	// 数据长度
	@SuppressWarnings("unused")
	private short length;
	
	@SuppressWarnings("unused")
	private byte tFrame;
	
	@SuppressWarnings("unused")
	private byte cFrame;

    @Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		super.channelInactive(ctx);
		ByteBuf bf = this.internalBuffer();
		bf.release();
	}
	
    @Override  
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { 
    	super.decode(ctx, in);  // 通过A5 5A协议头来拆包
    	
    	if(in==null || in.readableBytes()==0){
    		return in;
    	}

    	// 可读信息段比头部信息小
        if (in.readableBytes() < VALID_LENGHT) {  
            return null;
        }
        in.readBytes(address);
        type = in.readByte();
        length = in.readShort();
        tFrame = in.readByte();
        cFrame = in.readByte();
        
        // 读取正文
        byte[] body = new byte[in.readableBytes()-(RCR_SIZE+Time_SIZR)];
        in.readBytes(body);

        // 读取时间戳
        byte[] encryptionTime = new byte[in.readableBytes()-RCR_SIZE];
        in.readBytes(encryptionTime);
        
        NewReaderMessage message = new NewReaderMessage(address,type,body,encryptionTime);
        return message;
    }
}
